﻿using Sys.Model;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Core.EntityClient;
using System.Data.SqlClient;
using System.Linq;
using System.Text;

namespace Sys.Data
{
    /// <summary>
    /// 资源库上下文
    /// </summary>
    /// <typeparam name="T">实体类型</typeparam>
    public class RepositoryContext<T> where T : class
    {
        #region 上下文

        /// <summary>
        /// 获取实体数据类
        /// </summary>
        /// <returns>实体数据类</returns>
        public DbContext GetContext()
        {
            EntityConnectionStringBuilder ecsb = new EntityConnectionStringBuilder();

            ecsb.Metadata = string.Format(@"res://*/{0}.csdl|res://*/{0}.ssdl|res://*/{0}.msl", "Entities");
            ecsb.Provider = "System.Data.SqlClient";
            ecsb.ProviderConnectionString = ConfigurationManager.ConnectionStrings["Entities"].ConnectionString;

            return new EntitiesContainer(ecsb.ToString());
        }

        #endregion

        #region 公共上下文操作

        /// <summary>
        /// 获取类型化实体集
        /// </summary>
        /// <returns>类型化实体集</returns>
        public DbSet<T> Set()
        {
            return GetContext().Set<T>();
        }

        /// <summary>
        /// 注册添加实体状态并保存
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returns>受影响行数</returns>
        public int EntityAdded(T entity)
        {
            using (DbContext Context = GetContext())
            {
                Context.Set<T>().Attach(entity);
                Context.Entry(entity).State = EntityState.Added;

                return Context.SaveChanges();
            }
        }

        /// <summary>
        /// 批量注册添加实体状态并保存
        /// </summary>
        /// <param name="entities">实体集合</param>
        /// <returns>受影响行数</returns>
        public int EntitiesAdded(IEnumerable<T> entities)
        {
            using (DbContext Context = GetContext())
            {
                Context.Configuration.AutoDetectChangesEnabled = false;

                foreach (T entity in entities)
                {
                    Context.Set<T>().Attach(entity);
                    Context.Entry(entity).State = EntityState.Added;
                }

                Context.Configuration.AutoDetectChangesEnabled = true;

                return Context.SaveChanges();
            }
        }

        /// <summary>
        /// 注册更改实体状态并保存
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returns>受影响行数</returns>
        public int EntityModified(T entity)
        {
            using (DbContext Context = GetContext())
            {
                Context.Set<T>().Attach(entity);
                Context.Entry(entity).State = EntityState.Modified;

                return Context.SaveChanges();
            }
        }

        /// <summary>
        /// 批量注册更改实体状态并保存
        /// </summary>
        /// <param name="entities">实体集合</param>
        /// <returns>受影响行数</returns>
        public int EntitiesModified(IEnumerable<T> entities)
        {
            using (DbContext Context = GetContext())
            {
                Context.Configuration.AutoDetectChangesEnabled = false;

                foreach (T entity in entities)
                {
                    Context.Set<T>().Attach(entity);
                    Context.Entry(entity).State = EntityState.Modified;
                }

                Context.Configuration.AutoDetectChangesEnabled = true;

                return Context.SaveChanges();
            }
        }

        /// <summary>
        /// 注册删除实体状态并保存
        /// </summary>
        /// <param name="entity">实体</param>
        /// <returns>受影响行数</returns>
        public int EntityDeleted(T entity)
        {
            using (DbContext Context = GetContext())
            {
                Context.Set<T>().Attach(entity);
                Context.Entry(entity).State = EntityState.Deleted;

                return Context.SaveChanges();
            }
        }

        /// <summary>
        /// 批量注册删除实体状态并保存
        /// </summary>
        /// <param name="entities">实体</param>
        /// <returns>受影响行数</returns>
        public int EntitiesDeleted(IEnumerable<T> entities)
        {
            using (DbContext Context = GetContext())
            {
                Context.Configuration.AutoDetectChangesEnabled = false;

                foreach (T entity in entities)
                {
                    Context.Set<T>().Attach(entity);
                    Context.Entry(entity).State = EntityState.Deleted;
                }

                Context.Configuration.AutoDetectChangesEnabled = true;

                return Context.SaveChanges();
            }
        }

        #endregion
    }
}